package cn.hinglo.baseservice.interceptors;

import cn.hinglo.baseservice.annotation.IgnorePermission;
import cn.hinglo.baseservice.service.PermissionFeignService;
import cn.hinglo.common.constant.SystemConstant;
import cn.hinglo.common.entity.Result;
import cn.hinglo.common.enums.ExceptionEnum;
import cn.hinglo.common.utils.ResultUtils;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.util.List;


/**
 * @author HingLo
 * @createTime: 2018/11/15
 * @description: 权限拦截器配置
 */
@Component
@CacheConfig(cacheNames = SystemConstant.PERMISSION)
public class PermissionInterceptor extends BaseInterceptor {

    private final PermissionFeignService permissionFeignService;

    @Autowired
    public PermissionInterceptor(PermissionFeignService permissionFeignService) {
        this.permissionFeignService = permissionFeignService;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler, HandlerMethod handlerMethod)
            throws Exception { // 项目应用名称
        String ctx = request.getContextPath();
        // 访问的完整连接
        String uri = request.getRequestURI();
        // 权限判定需要去掉访问的应用名称
        String url = StrUtil.isBlank(ctx) ? uri : StrUtil.removePrefix(uri, ctx);
        String userId = (String) request.getAttribute(SystemConstant.PERMISSION_USER_ID);
        if (StrUtil.isBlank(userId)) {
            // 该校验是判断用户是否存在
            ResultUtils.error(response, ExceptionEnum.NOT403);
            return false;
        } else {
            // 查询该用户请求该权限是否有效
            List<String> list = findPermission(userId);
            // 判断是否包含权限url
            if (list != null && list.contains(url)) {
                return true;
            } else {
                ResultUtils.error(response, ExceptionEnum.NOT403);
                return false;
            }

        }
    }

    /**
     * 排除拥有的指定的注解的方法
     *
     * @return 是否忽略
     */
    @Override
    public Class<? extends Annotation> ignoreAnnotation() {
        return IgnorePermission.class;
    }

    /**
     * 权限查询
     *
     * @param userId 用户的id
     * @return 返回权限集合
     */
    @Cacheable(key = "#userId", unless = "#result==null")
    public List<String> findPermission(String userId) {
        Result<List<String>> result = permissionFeignService.getUserPermission(userId);
        if (result.getCode() == 200) {
            return result.getData();
        }
        return null;
    }

}
